//
//  GlobalMethod+Data.swift
//  全局方法 - 数据相关
//
//  Created by mini on 2025/4/28.
//

import Foundation

extension GlobalMethod {
    
    // MARK: - 清理本地用户数据
    static func clearUserDefault() {
        let defaults = UserDefaults.standard
        let dictionary = defaults.dictionaryRepresentation()
        for (key, _) in dictionary {
            if key.hasPrefix(LOCAL_KEY_PREFIX) {
                defaults.removeObject(forKey: key)
            }
        }
        defaults.synchronize()
    }
    
    // MARK: - 处理 key 的函数
    static func exchangeLocalKey(_ key: String) -> String {
        if !key.hasPrefix(LOCAL_KEY_PREFIX) {
            return "\(LOCAL_KEY_PREFIX)\(key)"
        }
        return key
    }
    
    // MARK: - 读写字符串
    class func writeStr(_ strValue: String, forKey strKey: String) {
        guard !strKey.isEmpty else { return }
        let key = exchangeLocalKey(strKey)
        let userDefaults = UserDefaults.standard
        userDefaults.set(strValue, forKey: key)
        userDefaults.synchronize()
    }
    
    class func readStrFromUserDefaults(forKey strKey: String) -> String {
        guard !strKey.isEmpty else { return "" }
        let key = exchangeLocalKey(strKey)
        let userDefaults = UserDefaults.standard
        if let strValue = userDefaults.string(forKey: key), !strValue.isEmpty {
            return strValue
        }
        return ""
    }
    
    // 不要前缀
    class func writeUnprefixedStr(_ strValue: String, forKey strKey: String) {
        guard !strKey.isEmpty else { return }
        let key = (strKey)
        let userDefaults = UserDefaults.standard
        userDefaults.set(strValue, forKey: key)
        userDefaults.synchronize()
    }
    
    class func readUnprefixedStrFromUserDefaults(forKey strKey: String) -> String {
        guard !strKey.isEmpty else { return "" }
        let key = (strKey)
        let userDefaults = UserDefaults.standard
        if let strValue = userDefaults.string(forKey: key), !strValue.isEmpty {
            return strValue
        }
        return ""
    }
    
    // MARK: - 读写BOOL
    class func writeBool(_ boolValue: Bool, forKey strKey: String, isPrefixed: Bool = true) {
        guard !strKey.isEmpty else { return }
        var key = exchangeLocalKey(strKey)
        if isPrefixed == false {
            key = strKey
        }
        let userDefaults = UserDefaults.standard
        userDefaults.set(boolValue, forKey: key)
        userDefaults.synchronize()
    }

    class func readBoolFromUserDefaults(forKey strKey: String, isPrefixed: Bool = true) -> Bool {
        guard !strKey.isEmpty else { return false }
        var key = exchangeLocalKey(strKey)
        if isPrefixed == false {
            key = strKey
        }
        let userDefaults = UserDefaults.standard
        return userDefaults.bool(forKey: key)
    }
    
    // MARK: - 读写Double
    class func writeDouble(_ doubleValue: Double, forKey strKey: String) {
        guard !strKey.isEmpty else { return }
        let key = (strKey)
        let userDefaults = UserDefaults.standard
        userDefaults.set(doubleValue, forKey: key)
        userDefaults.synchronize()
    }
    class func readDouble(forKey strKey: String) -> Double {
        guard !strKey.isEmpty else { return 0.0 }
        let key = (strKey)
        let userDefaults = UserDefaults.standard
        return userDefaults.double(forKey: key)
    }
    
    // MARK: - 读写Int
    class func writeInt(_ intValue: Int, forKey strKey: String) {
        guard !strKey.isEmpty else { return }
        let key = (strKey)
        let userDefaults = UserDefaults.standard
        userDefaults.set(intValue, forKey: key)
        userDefaults.synchronize()
    }
    class func readInt(forKey strKey: String) -> Int {
        guard !strKey.isEmpty else { return 0 }
        let key = (strKey)
        let userDefaults = UserDefaults.standard
        return userDefaults.integer(forKey: key)
    }
    
    // MARK: - 转换
    // 转换String to dic
    static func exchangeStringToDic(_ str: String?) -> [String: Any] {
        guard let str = str, !str.isEmpty else {
            return [:]
        }
        
        guard let data = str.data(using: .utf8) else {
            return [:]
        }
        
        do {
            if let dicReturn = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                return dicReturn
            } else {
                return [:]
            }
        } catch {
            return [:]
        }
    }
    
    // 转换String to Array
    static func exchangeStringToAry(_ str: String?) -> [Any] {
        guard let str = str, !str.isEmpty else {
            return []
        }
        
        guard let data = str.data(using: .utf8) else {
            return []
        }
        
        do {
            let aryReturn = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [Any]
            return aryReturn ?? []
        } catch {
            print("error json转换错误: \(error.localizedDescription)")
            return []
        }
    }
    
    // model 转 dic
    static func exchangeModelToDic(_ object: Any) -> [String: Any] {
        var dict = [String: Any]()
        let mirror = Mirror(reflecting: object)
        for child in mirror.children {
            if let label = child.label {
                let value = child.value
                if let optionalValue = value as? OptionalProtocol, optionalValue.isNone {
                    dict[label] = nil
                } else {
                    dict[label] = value
                }
            }
        }
        return dict
    }
    
    // model转换json
    static func exchangeModelToJson(_ model: Any?) -> String {
        guard let model = model as? [String: Any] else {
            return ""
        }
        
        do {
            let dataJson = try JSONSerialization.data(withJSONObject: model, options: [])
            if let strJson = String(data: dataJson, encoding: .utf8) {
                return strJson
            } else {
                return ""
            }
        } catch {
            return ""
        }
    }
    
    // 字典或者数组转Json
    static func exchangeDicToJson(object: Any?) -> String {
        guard let object = object else {
            print("error json转换错误")
            return ""
        }
        if JSONSerialization.isValidJSONObject(object) {
            do {
                let dataJson = try JSONSerialization.data(withJSONObject: object, options: [])
                if let strJson = String(data: dataJson, encoding: .utf8) {
                    return strJson
                }
            } catch {
                print("error json转换错误: \(error.localizedDescription)")
            }
        }
        return ""
    }
    
    // MARK: - 转化时间
    static func exchangeDateToStr(date: Date = Date(), dateFormat: String) -> String {
        let formatter = DateFormatter()
        // 设置日期格式
        formatter.dateFormat = dateFormat
        formatter.locale = Locale(identifier: "zh_CN")
        formatter.timeZone = TimeZone(identifier: "Asia/Shanghai")
        let dateString = formatter.string(from: date)
        return dateString
    }
    
    
    // MARK: - 安全的取值
    static func safeString(value: Optional<String>, defaultValue:String = "") -> String {
        if let result:String = value{
            return result
        }
        return defaultValue
    }
    static func safeInt(value: Optional<Int>,defaultValue:Int = 0) -> Int {
        if let result:Int = value{
            return result
        }
        return defaultValue
    }
    static func safeFloat(value: Optional<Float>,defaultValue:Float = 0.0) -> Float {
        if let result:Float = value{
            return result
        }
        return defaultValue
    }
    static func safeCGFloat(value: Optional<CGFloat>,defaultValue:CGFloat = 0.0) -> CGFloat {
        if let result:CGFloat = value{
            return result
        }
        return defaultValue
    }
    static func safeDouble(value: Optional<Double>,defaultValue:Double = 0) -> Double {
        if let result:Double = value{
            return result
        }
        return defaultValue
    }
    static func safeBool(value: Optional<Bool>,defaultValue:Bool = false) -> Bool {
        if let result:Bool = value{
            return result
        }
        return defaultValue
    }
    static func safeArray<T>(value: Optional<[T]>,defaultValue:[T] = []) -> [T] {
        if let result:[T] = value{
            return result
        }
        return defaultValue
    }
    static func safeDic(value: Optional<NSDictionary>,defaultValue:NSDictionary = NSDictionary.init()) -> NSDictionary {
        if let result:NSDictionary = value{
            return result
        }
        return defaultValue
    }
}


extension Optional: OptionalProtocol {
    var isNone: Bool {
        return self == nil
    }
}

protocol OptionalProtocol {
    var isNone: Bool { get }
}
